/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "common_module_registry.h"
#include "utils_log.h"

namespace El {
namespace Common {

ModuleRegistry& ModuleRegistry::GetInstance()
{
    static ModuleRegistry instance;
    return instance;
}

int32_t ModuleRegistry::RegisterModule(const ModuleInitCallback& callback, int32_t priority)
{
    if (!callback) {
        EL_ERROR("ModuleRegistry::RegisterModule: Invalid callback provided");
        return -1;
    }

    int32_t handle = moduleCallbacks_.Register(callback, priority);
    if (handle == -1) {
        EL_ERROR("ModuleRegistry::RegisterModule: Failed to register module callback");
        return -1;
    }

    EL_INFO("ModuleRegistry::RegisterModule: Module registered with handle {} and priority {}", handle, priority);
    return handle;
}

void ModuleRegistry::UnregisterModule(int32_t handle)
{
    moduleCallbacks_.Unregister(handle);
    EL_INFO("ModuleRegistry::UnregisterModule: Module with handle {} unregistered", handle);
}

bool ModuleRegistry::InitializeAllModules()
{
    if (moduleCallbacks_.IsEmpty()) {
        EL_INFO("ModuleRegistry::InitializeAllModules: No modules registered");
        return true;
    }

    EL_INFO("ModuleRegistry::InitializeAllModules: Starting initialization of registered modules");
    
    bool success = moduleCallbacks_.InvokeAll();
    
    if (success) {
        EL_INFO("ModuleRegistry::InitializeAllModules: All modules initialized successfully");
    } else {
        EL_ERROR("ModuleRegistry::InitializeAllModules: Some modules failed to initialize");
    }
    
    return success;
}

void ModuleRegistry::ClearAllModules()
{
    moduleCallbacks_.Clear();
    EL_INFO("ModuleRegistry::ClearAllModules: All module callbacks cleared");
}

bool ModuleRegistry::HasRegisteredModules() const
{
    return !moduleCallbacks_.IsEmpty();
}

} // namespace Common
} // namespace El